package class02;

public class Code02_改造随机函数 {
    /**
     * lib里的，不能改！  黑盒函数  1-5 随机
     */
    public static int f1() {
        return (int) (Math.random() * 5) + 1;
    }

    /**
     * 改造随机函数生成一个0和1的随机发生器
     */
    public static int f2() {
        int random = 0;
        do {
            random = f1();
        }
        while (random == 3);
        return random < 3 ? 0 : 1;
    }

    /**
     * 通过01的随机发生器 左移操作 制造一个 000-111的等概率发生器  即0-7等概率发生器
     */
    public static int f3() {
        return (f2() << 2) + (f2() << 1) + f2();
        //y 不等概率生成等概率的方法
        //return (y() << 2) + (y() << 1) + y();
    }

    /**
     * 由0-7等概率转换为0-6的等概率 7的时候重做
     */
    public static int f4() {
        int ans = 0;
        do {
            ans = f3();
        } while (ans == 7);
        return ans;
    }

    /**
     * 由0-6的等概率 转换为1-7的等概率发生器 直接加1就行了
     */
    public static int f5() {
        return f4() + 1;
    }

    public static void main(String[] args) {
        int doTimes = 10000000;
        int[] timeArray = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
        for (int i = 0; i < doTimes; i++) {
            timeArray[f5()]++;
        }
        for (int i = 0; i < timeArray.length; i++) {
            System.out.println("数字" + i + "次数：" + timeArray[i]);
        }
    }

    /**
     * 你只能知道，x会以固定概率返回0和1，但是x的内容，你看不到！      0/1  概率不等的返回  用它构造一个等概率发生器
     */
    public static int x() {
        return Math.random() < 0.84 ? 0 : 1;
    }

    /**
     * 运行两次 如果两次相同则重做 两次不同返回第一次的结果
     * 0    0   0.84*0.84
     * 0    1   0.84*0.16
     * 1    0   0.16*0.84
     * 1    1   0.16*0.16
     */
    public static int y() {
        int rst = 0;
        do {
            rst = x();
        } while (rst == x());
        return rst;
    }

}